home *** CD-ROM | disk | FTP | other *** search
/ IRIX 6.5 Complementary Applications 2004 February / SGI IRIX 6.5 Complementary Applications 2004 February.iso / dist / cde.idb / usr / dt / share / examples / motif / draganddrop / DNDDraw.c.z / DNDDraw.c
Encoding:
C/C++ Source or Header  |  2003-11-18  |  36.6 KB  |  1,348 lines

  1. /*
  2.  * DNDDraw.c
  3.  *
  4.  * Copyright 2000, Silicon Graphics, Inc.
  5.  * ALL RIGHTS RESERVED
  6.  * 
  7.  * UNPUBLISHED -- Rights reserved under the copyright laws of the United
  8.  * States.   Use of a copyright notice is precautionary only and does not
  9.  * imply publication or disclosure.
  10.  *
  11.  * U.S. GOVERNMENT RESTRICTED RIGHTS LEGEND:
  12.  * Use, duplication or disclosure by the Government is subject to restrictions
  13.  * as set forth in FAR 52.227.19(c)(2) or subparagraph (c)(1)(ii) of the Rights
  14.  * in Technical Data and Computer Software clause at DFARS 252.227-7013 and/or
  15.  * in similar or successor clauses in the FAR, or the DOD or NASA FAR
  16.  * Supplement.  Contractor/manufacturer is Silicon Graphics, Inc.,
  17.  * 2011 N. Shoreline Blvd. Mountain View, CA 94039-7311.
  18.  *
  19.  * THE CONTENT OF THIS WORK CONTAINS CONFIDENTIAL AND PROPRIETARY
  20.  * INFORMATION OF SILICON GRAPHICS, INC. ANY DUPLICATION, MODIFICATION,
  21.  * DISTRIBUTION, OR DISCLOSURE IN ANY FORM, IN WHOLE, OR IN PART, IS STRICTLY
  22.  * PROHIBITED WITHOUT THE PRIOR EXPRESS WRITTEN PERMISSION OF SILICON
  23.  * GRAPHICS, INC.
  24.  */
  25. /* 
  26.  * (c) Copyright 1989, 1990, 1991, 1992, 1993 OPEN SOFTWARE FOUNDATION, INC. 
  27.  * ALL RIGHTS RESERVED 
  28. */ 
  29. /* 
  30.  * Motif Release 1.2.2
  31. */ 
  32. #ifdef REV_INFO
  33. #ifndef lint
  34. static char rcsid[] = "$XConsortium: DNDDraw.c /main/cde1_maint/1 1995/07/14 13:59:16 drk $"
  35. #endif
  36. #endif
  37. /*
  38. *  (c) Copyright 1987, 1988, 1989 HEWLETT-PACKARD COMPANY */
  39. /*
  40.  *    file: DNDDraw.c
  41.  *
  42.  *    File containing all the drawing routines needed to run DNDDemo
  43.  *    program.
  44.  *
  45.  */
  46.  
  47. #include "DNDDemo.h"
  48.  
  49.  
  50. /* The following character arrays hold the bits for
  51.  * the source and state icons for both 32x32 and 16x16 drag icons.
  52.  * The source is a color palette icon and the state is a paint brush icon.
  53.  */
  54. unsigned char SOURCE_ICON_BITS[] = {
  55.     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0xaa, 0x02,
  56.     0x00, 0x50, 0x55, 0x07, 0x00, 0x28, 0x00, 0x0c, 0x00, 0x94, 0x42, 0x19,
  57.     0x00, 0xca, 0xe5, 0x33, 0x00, 0x85, 0xc6, 0x33, 0x80, 0x42, 0xe7, 0x33,
  58.     0x40, 0x81, 0xc3, 0x31, 0xa0, 0x00, 0x00, 0x38, 0x50, 0x00, 0x00, 0x1c,
  59.     0x28, 0x00, 0x00, 0x0e, 0x90, 0x02, 0x00, 0x07, 0xc8, 0x05, 0x80, 0x03,
  60.     0x90, 0x07, 0xc0, 0x01, 0x48, 0x05, 0xe0, 0x00, 0x90, 0x03, 0x70, 0x00,
  61.     0x08, 0x00, 0x30, 0x00, 0x10, 0x14, 0x30, 0x00, 0x08, 0x2a, 0x30, 0x00,
  62.     0x10, 0x34, 0x30, 0x00, 0x28, 0x2a, 0x60, 0x00, 0x50, 0x9c, 0xe2, 0x00,
  63.     0xa0, 0x40, 0xc4, 0x01, 0x40, 0x01, 0x84, 0x01, 0x80, 0x42, 0x84, 0x03,
  64.     0x00, 0x85, 0x03, 0x03, 0x00, 0x0a, 0x00, 0x03, 0x00, 0xf4, 0xff, 0x03,
  65.     0x00, 0xf8, 0xff, 0x01, 0x00, 0x00, 0x00, 0x00};
  66.  
  67. unsigned char SOURCE_ICON_MASK[] = {
  68.     0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0xff, 0x07, 0x00, 0xf8, 0xff, 0x0f,
  69.     0x00, 0xfc, 0xff, 0x1f, 0x00, 0xfe, 0xff, 0x3f, 0x00, 0xff, 0xff, 0x7f,
  70.     0x80, 0xff, 0xff, 0x7f, 0xc0, 0xff, 0xff, 0x7f, 0xe0, 0xff, 0xff, 0x7f,
  71.     0xf0, 0xff, 0xff, 0x7f, 0xf8, 0xff, 0xff, 0x7f, 0xfc, 0xff, 0xff, 0x7f,
  72.     0xfc, 0xff, 0xff, 0x3f, 0xfc, 0xff, 0xff, 0x1f, 0xfc, 0xff, 0xff, 0x0f,
  73.     0xfc, 0xff, 0xff, 0x07, 0xfc, 0xff, 0xff, 0x03, 0xfc, 0xff, 0xff, 0x01,
  74.     0xfc, 0xff, 0xff, 0x00, 0xfc, 0xff, 0x7f, 0x00, 0xfc, 0xff, 0x7f, 0x00,
  75.     0xfc, 0xff, 0xff, 0x00, 0xfc, 0xff, 0xff, 0x01, 0xfc, 0xff, 0xff, 0x03,
  76.     0xf8, 0xff, 0xff, 0x03, 0xf0, 0xff, 0xff, 0x07, 0xe0, 0xff, 0xff, 0x07,
  77.     0xc0, 0xff, 0xff, 0x07, 0x80, 0xff, 0xff, 0x07, 0x00, 0xff, 0xff, 0x07,
  78.     0x00, 0xfe, 0xff, 0x07, 0x00, 0xfc, 0xff, 0x03};
  79.  
  80. unsigned char STATE_ICON_BITS[] = {
  81.     0x00, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00,
  82.     0xf8, 0x01, 0x00, 0x00, 0xf8, 0x01, 0x00, 0x00, 0xf8, 0x03, 0x00, 0x00,
  83.     0xf0, 0x03, 0x00, 0x00, 0xf0, 0x07, 0x00, 0x00, 0xc0, 0x0d, 0x00, 0x00,
  84.     0x00, 0x1b, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x00, 0x00, 0x7e, 0x00, 0x00,
  85.     0x00, 0xfc, 0x00, 0x00, 0x00, 0xf8, 0x01, 0x00, 0x00, 0xf0, 0x03, 0x00,
  86.     0x00, 0xe0, 0x07, 0x00, 0x00, 0xc0, 0x0f, 0x00, 0x00, 0x80, 0x1f, 0x00,
  87.     0x00, 0x00, 0x3f, 0x00, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x00, 0xfc, 0x00,
  88.     0x00, 0x00, 0xf8, 0x01, 0x00, 0x00, 0xf0, 0x01, 0x00, 0x00, 0xe0, 0x03,
  89.     0x00, 0x00, 0xc0, 0x07, 0x00, 0x00, 0x80, 0x0f, 0x00, 0x00, 0x00, 0x1f,
  90.     0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 0x38,
  91.     0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0xc0};
  92.  
  93. unsigned char STATE_ICON_MASK[] = {
  94.     0x3f, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, 0x03, 0x00, 0x00,
  95.     0xfc, 0x03, 0x00, 0x00, 0xfc, 0x07, 0x00, 0x00, 0xfc, 0x07, 0x00, 0x00,
  96.     0xfc, 0x07, 0x00, 0x00, 0xf8, 0x07, 0x00, 0x00, 0xf8, 0x0f, 0x00, 0x00,
  97.     0xe0, 0x1f, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x00, 0x00, 0x7e, 0x00, 0x00,
  98.     0x00, 0xfc, 0x00, 0x00, 0x00, 0xf8, 0x01, 0x00, 0x00, 0xf0, 0x03, 0x00,
  99.     0x00, 0xe0, 0x07, 0x00, 0x00, 0xc0, 0x0f, 0x00, 0x00, 0x80, 0x1f, 0x00,
  100.     0x00, 0x00, 0x3f, 0x00, 0x00, 0x00, 0xfe, 0x01, 0x00, 0x00, 0xfc, 0x03,
  101.     0x00, 0x00, 0xf8, 0x03, 0x00, 0x00, 0xf0, 0x07, 0x00, 0x00, 0xe0, 0x0f,
  102.     0x00, 0x00, 0xc0, 0x1f, 0x00, 0x00, 0x80, 0x3f, 0x00, 0x00, 0x00, 0x7f,
  103.     0x00, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x00, 0xfe,
  104.     0x00, 0x00, 0x00, 0xfc, 0x00, 0x00, 0x00, 0xf0};
  105.  
  106. unsigned char INVALID_ICON_BITS[] = {
  107.     0x00, 0xe0, 0x0f, 0x00, 0x00, 0xfc, 0x7f, 0x00, 0x00, 0xff, 0xff, 0x01,
  108.     0x80, 0xff, 0xff, 0x03, 0xc0, 0x1f, 0xf0, 0x07, 0xe0, 0x07, 0xc0, 0x0f,
  109.     0xf0, 0x07, 0x00, 0x1f, 0xf8, 0x0f, 0x00, 0x3e, 0xf8, 0x1f, 0x00, 0x3c,
  110.     0xfc, 0x3f, 0x00, 0x7c, 0x3c, 0x7f, 0x00, 0x78, 0x3c, 0xfe, 0x00, 0x78,
  111.     0x1e, 0xfc, 0x01, 0xf0, 0x1e, 0xf8, 0x03, 0xf0, 0x1e, 0xf0, 0x07, 0xf0,
  112.     0x1e, 0xe0, 0x0f, 0xf0, 0x1e, 0xc0, 0x1f, 0xf0, 0x1e, 0x80, 0x3f, 0xf0,
  113.     0x1e, 0x00, 0x7f, 0xf0, 0x3c, 0x00, 0xfe, 0x78, 0x3c, 0x00, 0xfc, 0x79,
  114.     0x7c, 0x00, 0xf8, 0x7f, 0x78, 0x00, 0xf0, 0x3f, 0xf8, 0x00, 0xe0, 0x3f,
  115.     0xf0, 0x01, 0xc0, 0x1f, 0xe0, 0x07, 0xc0, 0x0f, 0xc0, 0x1f, 0xf0, 0x07,
  116.     0x80, 0xff, 0xff, 0x03, 0x00, 0xff, 0xff, 0x01, 0x00, 0xfc, 0x7f, 0x00,
  117.     0x00, 0xe0, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00};
  118.  
  119. unsigned char SMALL_SOURCE_ICON_BITS[] = {
  120.     0x80, 0x1f, 0x40, 0x60, 0x20, 0x91, 0x90, 0xaa, 0x08, 0x91, 0x08, 0x40,
  121.     0x08, 0x20, 0x08, 0x10, 0x28, 0x10, 0x78, 0x10, 0x28, 0x20, 0x08, 0x41,
  122.     0x90, 0x43, 0x20, 0x21, 0x40, 0x10, 0x80, 0x0f};
  123.  
  124. unsigned char SMALL_SOURCE_ICON_MASK[] = {
  125.     0x80, 0x1f, 0xc0, 0x7f, 0xe0, 0xff, 0xf0, 0xff, 0xf8, 0xff, 0xf8, 0x7f,
  126.     0xf8, 0x3f, 0xf8, 0x1f, 0xf8, 0x1f, 0xf8, 0x1f, 0xf8, 0x3f, 0xf8, 0x7f,
  127.     0xf0, 0x7f, 0xe0, 0x3f, 0xc0, 0x1f, 0x80, 0x0f};
  128.  
  129. unsigned char SMALL_STATE_ICON_BITS[] = {
  130.     0x0f, 0x00, 0x1e, 0x00, 0x1e, 0x00, 0x3c, 0x00, 0x50, 0x00, 0xe0, 0x00,
  131.     0xc0, 0x01, 0x80, 0x03, 0x00, 0x07, 0x00, 0x0e, 0x00, 0x1c, 0x00, 0x18,
  132.     0x00, 0x20, 0x00, 0x40, 0x00, 0x80, 0x00, 0x00};
  133.  
  134. unsigned char SMALL_STATE_ICON_MASK[] = {
  135.     0x0f, 0x00, 0x1e, 0x00, 0x1e, 0x00, 0x3c, 0x00, 0x70, 0x00, 0xe0, 0x00,
  136.     0xc0, 0x01, 0x80, 0x03, 0x00, 0x07, 0x00, 0x0e, 0x00, 0x1c, 0x00, 0x18,
  137.     0x00, 0x20, 0x00, 0x40, 0x00, 0x80, 0x00, 0x00};
  138.  
  139. unsigned char SMALL_INVALID_ICON_BITS[] = {
  140.     0xe0, 0x03, 0xf8, 0x0f, 0x1c, 0x1c, 0x1e, 0x30, 0x3e, 0x30, 0x73, 0x60,
  141.     0xe3, 0x60, 0xc3, 0x61, 0x83, 0x63, 0x03, 0x67, 0x06, 0x3e, 0x06, 0x3c,
  142.     0x1c, 0x1c, 0xf8, 0x0f, 0xe0, 0x03, 0x00, 0x00};
  143.  
  144.  
  145. /* Globals variables */
  146. AppInfo appInfo;
  147.  
  148.  
  149. /* This is a string to pixel conversion function. */
  150. Pixel 
  151. #ifdef _NO_PROTO
  152. GetColor(colorstr)
  153. char *colorstr;
  154. #else
  155. GetColor(char *colorstr)
  156. #endif /* _NO_PROTO */
  157. {
  158.  
  159.     XrmValue    from, to;
  160.  
  161.     from.size = strlen(colorstr) +1;
  162.     if (from.size < sizeof(String))
  163.         from.size = sizeof(String);
  164.     from.addr = colorstr;
  165.     to.addr = NULL;
  166.     XtConvert(topLevel, XmRString, &from, XmRPixel, &to);
  167.  
  168.     if (to.addr != NULL)
  169.         return ((Pixel) *((Pixel *) to.addr));
  170.     else
  171.         return ( (XtArgVal) NULL);
  172.  
  173. }
  174.  
  175.  
  176. /* This procedure is used to initalize the application information structure */
  177. void
  178. #ifdef _NO_PROTO
  179. InitializeAppInfo()
  180. #else /* _NO_PROTO */
  181. InitializeAppInfo(void)
  182. #endif /* _NO_PROTO */
  183. {
  184.  
  185.     if (!appInfo) {
  186.  
  187.         appInfo = (AppInfo) XtMalloc(sizeof(AppInfoRec));
  188.         appInfo->rectGC = NULL;
  189.         appInfo->currentColor = 0;
  190.         appInfo->rectDpyTable = NULL;
  191.         appInfo->rectsAllocd = 0;
  192.         appInfo->numRects = 0;
  193.         appInfo->highlightRect = NULL;
  194.         appInfo->clearRect = NULL;
  195.         appInfo->doMove = True;
  196.         appInfo->creatingRect = True;
  197.         appInfo->operation = XmDROP_MOVE;
  198.         appInfo->maxCursorWidth = 64;
  199.         appInfo->maxCursorHeight = 64;
  200.         appInfo->rectX = 0;
  201.         appInfo->rectY = 0;
  202.         appInfo->rectX2 = 0;
  203.         appInfo->rectY2 = 0;
  204.  
  205.     }
  206.  
  207. }
  208.  
  209.  
  210. /* This procedure sets the color in the GC for drawing the rectangles
  211.  * in a new color.
  212.  */
  213. void
  214. #ifdef _NO_PROTO
  215. SetColor(display, color)
  216. Display *display;
  217. Pixel color;
  218. #else
  219. SetColor(Display *display, Pixel color)
  220. #endif /* _NO_PROTO */
  221. {
  222.  
  223.     /*
  224.      * if the GC already has a foreground of this color,
  225.      * it would be wasteful to reset the color
  226.      */
  227.     if (color != appInfo->currentColor) {
  228.         XSetForeground(display, appInfo->rectGC, (unsigned long) color);
  229.         appInfo->currentColor = color;
  230.     }
  231.  
  232. }
  233.  
  234.  
  235. /* This function draws the rectangle in the color provided */
  236. static int
  237. #ifdef _NO_PROTO
  238. RectDraw(display, window, rect)
  239. Display *display;
  240. Window window;
  241. RectPtr rect;
  242. #else
  243. RectDraw(Display *display, Window window, RectPtr rect)
  244. #endif /* _NO_PROTO */
  245. {
  246.  
  247.     SetColor(display, rect->color);
  248.     XFillRectangle(display, window, appInfo->rectGC, rect->x,
  249.                    rect->y, rect->width, rect->height);
  250.  
  251. }
  252.  
  253.  
  254. /* This procedure draws the rectangle highlight in a specified color*/
  255. static void
  256. #ifdef _NO_PROTO
  257. RectDrawHighlight(w, rect, color )
  258. Widget w;
  259. RectPtr rect;
  260. Pixel color;
  261. #else
  262. RectDrawHighlight( Widget w, RectPtr rect, Pixel color )
  263. #endif /* _NO_PROTO */
  264. {
  265.  
  266.     Display *display = XtDisplay(w);
  267.     Window window = XtWindow(w);
  268.     Pixel currentColor = rect->color;
  269.     XGCValues values;
  270.  
  271.     values.foreground = color;
  272.     XChangeGC(display, appInfo->rectGC, GCForeground, &values);
  273.  
  274.     XDrawRectangle(display, window, appInfo->rectGC,
  275.                    rect->x + 1, rect->y + 1,
  276.                    rect->width - HIGHLIGHT_THICKNESS,
  277.                    rect->height - HIGHLIGHT_THICKNESS);
  278.  
  279.     /* Return the GC to it's previous state */
  280.     values.foreground = appInfo->currentColor = currentColor;
  281.     XChangeGC(display, appInfo->rectGC, GCForeground, &values);
  282.  
  283. }
  284.  
  285.  
  286. /* This procedure handles redrawing the rectangles.  It draws
  287.  * them according to the order in the rectangle display table.
  288.  * The rectangles at the top of the table are drawn first.
  289.  */
  290. void
  291. #ifdef _NO_PROTO
  292. RedrawRectangles(w)
  293. Widget w;
  294. #else
  295. RedrawRectangles(Widget w)
  296. #endif /* _NO_PROTO */
  297. {
  298.  
  299.     Display *display = XtDisplay(w);
  300.     RectPtr rect;
  301.     Window window = XtWindow(w);
  302.     int i;
  303.  
  304.     for (i = 0; i < appInfo->numRects; i++) {
  305.  
  306.         rect = appInfo->rectDpyTable[i];
  307.         /* Only draw the rectangles that haven't been cleared */
  308.         if (rect != appInfo->clearRect) {
  309.             RectDraw(display, window, rect);
  310.         }
  311.         /* Draw the rectangle highlight of the highlight rectangle */
  312.         if (rect == appInfo->highlightRect) {
  313.             RectDrawHighlight(w, rect, GetColor(HIGHLIGHT_COLOR));
  314.         }
  315.  
  316.     }
  317.  
  318. }
  319.  
  320.  
  321. /* This procedure will clear the current rectangle and redraw any rectangles
  322.  * that were partially cleared by the rectangle that was deleted.
  323.  */
  324. /* ARGSUSED */
  325. void
  326. #ifdef _NO_PROTO
  327. RectHide(display, window, rect)
  328. Display *display;
  329. Window window;
  330. RectPtr rect;
  331. #else
  332. RectHide(Display *display, Window window, RectPtr rect)
  333. #endif /* _NO_PROTO */
  334. {
  335.  
  336.     Pixel background, oldColor;
  337.     Arg args[1];
  338.  
  339.     /* Get the background of the drawing area. */
  340.     XtSetArg(args[0], XmNbackground, &background);
  341.     XtGetValues(drawingArea, args, 1);
  342.  
  343.     /* Save the old color for restoration purposes. */
  344.     oldColor = rect->color;
  345.  
  346.     /* Clear the rectangle */
  347.     rect->color = background;
  348.     RectDraw(display, window, rect);
  349.     appInfo->clearRect = rect;
  350.  
  351.     /* redraw the rest of the rectangles */
  352.     RedrawRectangles(drawingArea);
  353.  
  354.     /* restore the rectangle color */
  355.     rect->color = oldColor;
  356.  
  357. }
  358.  
  359. /* This procedure draws the stipple rectangle that is used in marking
  360.  * the old rectangle position during a rectangle move operation.
  361.  */
  362. /* ARGSUSED */
  363. void
  364. #ifdef _NO_PROTO
  365. RectDrawStippled(display, window, rect)
  366. Display *display;
  367. Window window;
  368. RectPtr rect;
  369. #else
  370. RectDrawStippled(Display *display, Window window, RectPtr rect)
  371. #endif /* _NO_PROTO */
  372. {
  373.  
  374.     register int x = rect->x;
  375.     register int y = rect->y;
  376.     register Dimension width = rect->width;
  377.     register Dimension height = rect->height;
  378.     XGCValues values;
  379.     XSegment segments[4];
  380.  
  381.     /* Set the rectangle color */
  382.     values.foreground = appInfo->currentColor = rect->color;
  383.     XChangeGC(display, appInfo->rectGC, GCForeground , &values);
  384.  
  385.     /* Create the segments for drawing the stippled rectangle */
  386.     segments[0].x1 = segments[2].x1 = x;
  387.     segments[0].y1 = segments[0].y2 = y;
  388.     segments[0].x2 = x + width - 1;
  389.     segments[1].x1 = segments[1].x2 = x + width - 1;
  390.     segments[1].y1 = segments[3].y1 = y;
  391.     segments[3].y2 = y + height;
  392.     segments[2].y1 = segments[2].y2 = y + height - 1;
  393.     segments[3].x1 = segments[3].x2 = x;
  394.     segments[2].x2 = x + width;
  395.     segments[1].y2 = y + height;
  396.  
  397.     /* Set the line attributes and draw */
  398.     XSetLineAttributes(display, appInfo->rectGC, 1, LineOnOffDash,
  399.         CapButt, JoinMiter);
  400.     XDrawSegments (display, window, appInfo->rectGC, segments, 4);
  401.  
  402.     /* restore the default line settings */
  403.     values.line_width = HIGHLIGHT_THICKNESS;
  404.     values.line_style = LineSolid;
  405.     XChangeGC(display, appInfo->rectGC, GCLineWidth | GCLineStyle, &values);
  406.  
  407. }
  408.  
  409.  
  410. /* This procedure sets the highlight rectangle and
  411.  * redraws the rectangles.  The expose routine will draw
  412.  * the highlight around the highlighted rectangle.
  413.  */
  414. /* ARGSUSED */
  415. void
  416. #ifdef _NO_PROTO
  417. RectHighlight(w, rect)
  418. Widget w;
  419. RectPtr rect;
  420. #else
  421. RectHighlight(Widget w, RectPtr rect)
  422. #endif /* _NO_PROTO */
  423. {
  424.  
  425.     if (appInfo->highlightRect != rect) {
  426.         appInfo->highlightRect = rect;
  427.         RedrawRectangles(w);
  428.     }
  429.  
  430. }
  431.  
  432. /* This procedure sets the highlight rectangle to NULL and
  433.  * redraws the rectangles.  The expose routine will clear
  434.  * the highlight around the highlighted rectangle.
  435.  */
  436. /* ARGSUSED */
  437. void
  438. #ifdef _NO_PROTO
  439. RectUnhighlight(w)
  440. Widget w;
  441. #else
  442. RectUnhighlight(Widget w)
  443. #endif /* _NO_PROTO */
  444. {
  445.  
  446.     if (appInfo->highlightRect) {
  447.         appInfo->highlightRect = NULL;
  448.         RedrawRectangles(w);
  449.     }
  450.  
  451. }
  452.  
  453. /* This function creates and initialized a new rectangle */
  454. RectPtr 
  455. #ifdef _NO_PROTO
  456. RectCreate(x, y, width, height, color, pixmap)
  457. Position x;
  458. Position y;
  459. Dimension width;
  460. Dimension height;
  461. Pixel color;
  462. Pixmap pixmap;
  463. #else
  464. RectCreate(Position x, Position y, Dimension width,
  465. Dimension height, Pixel color, Pixmap pixmap)
  466. #endif /* _NO_PROTO */
  467. {
  468.  
  469.     RectPtr rect;
  470.  
  471.     rect = (RectPtr)  XtMalloc(sizeof(RectStruct));
  472.  
  473.     rect->x = x;
  474.     rect->y = y;
  475.     rect->width = width;
  476.     rect->height = height;
  477.     rect->color = color;
  478.     rect->pixmap = pixmap;
  479.  
  480.     return(rect);
  481.  
  482. }
  483.  
  484.  
  485. /* This procedure will move the rectangle to the end of the rectangle
  486.  * display table (effectively raising it to top of the displayed
  487.  * rectangles).
  488.  */
  489. static void
  490. #ifdef _NO_PROTO
  491. RectToTop(rect)
  492. RectPtr rect;
  493. #else
  494. RectToTop(RectPtr rect)
  495. #endif /* _NO_PROTO */
  496. {
  497.  
  498.     int    i, j;
  499.  
  500.  
  501.     if (rect) {
  502.  
  503.         /* Get the index to the target rectangle */
  504.         for (i = 0; i < appInfo->numRects; i++) {
  505.             if (appInfo->rectDpyTable[i] == rect)
  506.                 break;
  507.         }
  508.  
  509.         /* Shift the other rectangles downward */
  510.         for (j = i; j < appInfo->numRects - 1; j++)
  511.             appInfo->rectDpyTable[j] = appInfo->rectDpyTable[j + 1];
  512.  
  513.         /* Place the target rectangle at the end */
  514.         appInfo->rectDpyTable[j] = rect;
  515.  
  516.     }
  517.  
  518. }
  519.  
  520.  
  521. /* This procedure raises the rectangle to the top of the drawing area */
  522. /* ARGSUSED */
  523. static void
  524. #ifdef _NO_PROTO
  525. RectRaise(w, rect)
  526. Widget w;
  527. RectPtr rect;
  528. #else
  529. RectRaise(Widget w, RectPtr rect)
  530. #endif /* _NO_PROTO */
  531. {
  532.  
  533.     RectToTop(rect);
  534.     RedrawRectangles(w);
  535.  
  536. }
  537.  
  538.  
  539. /* This procedure moves the rectangle the the end of the display stack,
  540.  * decrements the number of rectangles, and then frees the rectangle.
  541.  */
  542. void
  543. #ifdef _NO_PROTO
  544. RectFree(rect)
  545. RectPtr rect;
  546. #else
  547. RectFree(RectPtr rect)
  548. #endif /* _NO_PROTO */
  549. {
  550.  
  551.     /* if the rectangle is registered */
  552.     if (rect) {
  553.  
  554.         RectToTop(rect);
  555.         appInfo->numRects--;
  556.         XtFree((char *)rect);
  557.  
  558.     }
  559.  
  560. }
  561.  
  562.  
  563. /* This procedure added the rectangle to the rectangle display table
  564.  * (reallocing the table if necessary).
  565.  */
  566. void
  567. #ifdef _NO_PROTO
  568. RectRegister(rect, x, y)
  569. RectPtr rect;
  570. #else
  571. RectRegister(RectPtr rect, Position x, Position y)
  572. #endif /* _NO_PROTO */
  573. {
  574.  
  575.     appInfo->numRects++;
  576.  
  577.     /* rectangles can have their x and y values reset at registration time */
  578.     rect->x = x;
  579.     rect->y = y;
  580.  
  581.     /* realloc the table if it is too small */
  582.     if (appInfo->numRects > appInfo->rectsAllocd) {
  583.  
  584.         /* grow geometrically */
  585.         appInfo->rectsAllocd *= 2;
  586.         appInfo->rectDpyTable = (RectPtr *) 
  587.                                  XtRealloc((char *) appInfo->rectDpyTable,
  588.                                            (unsigned) (sizeof(RectPtr) * 
  589.                                            appInfo->rectsAllocd));
  590.  
  591.     }
  592.  
  593.     /* Add to end of display table */
  594.     appInfo->rectDpyTable[appInfo->numRects - 1] = rect;
  595.  
  596. }
  597.  
  598.  
  599. /* This function find the top most rectangle at the given x,y position */
  600. RectPtr 
  601. #ifdef _NO_PROTO
  602. RectFind(x, y)
  603. Position x;
  604. Position y;
  605. #else
  606. RectFind(Position x, Position y)
  607. #endif /* _NO_PROTO */
  608. {
  609.  
  610.     RectPtr rect;
  611.     int     i;
  612.  
  613.     /*
  614.      * Search from the end of the rectangle display table
  615.         * to find the top most rectangle.
  616.         */
  617.     for (i = appInfo->numRects - 1; i >= 0; i--) {
  618.  
  619.         rect = appInfo->rectDpyTable[i];
  620.         if (rect->x <= x && rect->x + (int)rect->width >= x &&
  621.             rect->y <= y && rect->y + (int)rect->height >= y) {
  622.             return(rect);
  623.         }
  624.  
  625.     }
  626.  
  627.     /* If a rectangle is not found return NULL */
  628.     return(NULL);
  629.  
  630. }
  631.  
  632.  
  633. /* This procedure sets the retangle's color */
  634. void
  635. #ifdef _NO_PROTO
  636. RectSetColor(rect, display, window, color)
  637. RectPtr rect;
  638. Display *display;
  639. Window window;
  640. Pixel color;
  641. #else
  642. RectSetColor(RectPtr rect, Display *display, Window window, Pixel color)
  643. #endif /* _NO_PROTO */
  644. {
  645.  
  646.     rect->color = color;
  647.     RectDraw(display, window, rect);
  648.  
  649. }
  650.  
  651.  
  652. /* This function gets the retangle's color */
  653. Pixel
  654. #ifdef _NO_PROTO
  655. RectGetColor(rect)
  656. RectPtr rect;
  657. #else
  658. RectGetColor(RectPtr rect)
  659. #endif /* _NO_PROTO */
  660. {
  661.     return(rect->color);
  662. }
  663.  
  664.  
  665. /* This procedure sets the retangle's pixmap. The pixmap portion of the
  666.  * rectangle is not currently being used.
  667.  */
  668. /* ARGSUSED */
  669. void
  670. #ifdef _NO_PROTO
  671. RectSetPixmap(rect, display, window, pixmap)
  672. RectPtr rect;
  673. Display *display;
  674. Window window;
  675. Pixmap pixmap;
  676. #else
  677. RectSetPixmap(RectPtr rect, Display *display, Window window, Pixmap pixmap)
  678. #endif /* _NO_PROTO */
  679. {
  680.  
  681.     rect->pixmap = pixmap; /* not currently being looked at */
  682.     RectDraw(display, window, rect);
  683.  
  684. }
  685.  
  686.  
  687. /* This function gets the retangle's pixmap. The pixmap portion of the
  688.  * rectangle is not currently being used.
  689.  */
  690. /* ARGSUSED */
  691. static Pixmap
  692. #ifdef _NO_PROTO
  693. RectGetPixmap(rect)
  694. RectPtr rect;
  695. #else
  696. RectGetPixmap(RectPtr rect)
  697. #endif /* _NO_PROTO */
  698. {
  699.     return (rect->pixmap);
  700. }
  701.  
  702.  
  703. /* This procedure gets the retangle's height and width.  */
  704. /* ARGSUSED */
  705. static void
  706. #ifdef _NO_PROTO
  707. RectGetDimensions(rect, width, height)
  708. RectPtr rect;
  709. Dimension *width;
  710. Dimension *height;
  711. #else
  712. RectGetDimensions(RectPtr rect, Dimension *width, Dimension *height)
  713. #endif /* _NO_PROTO */
  714. {
  715.  
  716.     *width = rect->width;
  717.     *height = rect->height;
  718.  
  719. }
  720.  
  721.  
  722. /* This function creates the rectangle bitmaps for the icon. */
  723. Pixmap
  724. #ifdef _NO_PROTO
  725. GetBitmapFromRect(w, rect, background, foreground, widthRtn, heightRtn)
  726. Widget w;
  727. RectPtr rect;
  728. Pixel background;
  729. Pixel foreground;
  730. Dimension *widthRtn;
  731. Dimension *heightRtn;
  732. #else
  733. GetBitmapFromRect(Widget w, RectPtr rect, Pixel background, Pixel foreground,
  734. Dimension *widthRtn, Dimension *heightRtn)
  735. #endif /* _NO_PROTO */
  736. {
  737.  
  738.     Dimension width, height, maxHeight, maxWidth;
  739.     GC fillGC;
  740.     Pixmap icon_pixmap;
  741.     Display *display = XtDisplay(w);
  742.     XGCValues values;
  743.  
  744.     RectGetDimensions(rect, &width, &height);
  745.  
  746.     /* Get the maximum allowable width and height allowed by the cursor */
  747.     maxWidth = appInfo->maxCursorWidth;
  748.     maxHeight = appInfo->maxCursorHeight;
  749.  
  750.     /* if the dimensions aren't within the allowable dimensions resize
  751.    * then proportionally
  752.    */
  753.     if (maxWidth < width || maxHeight < height) {
  754.  
  755.         if (width > height) {
  756.             height = (Dimension)(height * maxWidth) / (Dimension)width;
  757.             width = appInfo->maxCursorWidth;
  758.         } else {
  759.             width = (Dimension)(width * maxHeight) / (Dimension)height;
  760.             height = appInfo->maxCursorHeight;
  761.         }
  762.  
  763.     }
  764.  
  765.     /* Create a depth 1 pixmap (bitmap) for use with the drag icon */
  766.     icon_pixmap = XCreatePixmap(display, XtWindow(w), width, height, 1);
  767.  
  768.     /* create a GC for drawing into the bitmap */
  769.     fillGC = XCreateGC(display, icon_pixmap, 0, (XGCValues *)NULL);
  770.  
  771.     /* fill the bitmap with 0's as a starting point */
  772.     XFillRectangle(display, icon_pixmap, fillGC, 0, 0, width, height);
  773.  
  774.     /* Change GC to be able to create the rectangle with 1's on the bitmap */
  775.     values.foreground = 1;
  776.     XChangeGC(display, fillGC, GCForeground, &values);
  777.  
  778.     /*
  779.      * This draw a filled rectangle.  If only a outline is desired
  780.      * use the XDrawRectangle() call.  Note: the outline does not
  781.      * produce very effect icon melting.
  782.      */
  783.     XFillRectangle(display, icon_pixmap, fillGC, 0, 0, width, height);
  784.  
  785.     /* Free the fill GC */
  786.     XFreeGC(display, fillGC);
  787.  
  788.     *widthRtn = width;
  789.     *heightRtn = height;
  790.  
  791.     return(icon_pixmap);
  792.  
  793. }
  794.  
  795.  
  796. /***************************************************************************
  797.  ***************************************************************************
  798.                   Functions used in Drawing Outlines:
  799.  ***************************************************************************
  800.  ***************************************************************************/
  801.  
  802. /*
  803.  * This procedure changes the GC to do rubberband
  804.  * drawing of a rectangle frame .
  805.  */
  806. static void
  807. #ifdef _NO_PROTO
  808. SetXorGC(w)
  809. Widget w;
  810. #else
  811. SetXorGC(Widget w)
  812. #endif /* _NO_PROTO */
  813. {
  814.  
  815.     unsigned long valueMask = GCFunction | GCForeground | GCLineWidth;
  816.     XGCValues values;
  817.     Pixel bg, fg;
  818.  
  819.  
  820.     XtVaGetValues (w, XmNbackground, &bg, XmNforeground, &fg, NULL);
  821.  
  822.     values.function = GXxor;
  823.     values.foreground = fg^bg;   /* fix 5127 */
  824.     values.line_width = 1;
  825.     XChangeGC(XtDisplay(w), appInfo->rectGC, valueMask, &values);
  826.  
  827. }
  828.  
  829.  
  830. /* This procedure returns the GC to it's initial state.  */
  831. static void
  832. #ifdef _NO_PROTO
  833. SetNormGC(w)
  834. Widget w;
  835. #else
  836. SetNormGC(Widget w)
  837. #endif /* _NO_PROTO */
  838. {
  839.  
  840.     unsigned long valueMask = GCFunction | GCLineWidth | GCForeground;
  841.     XGCValues values;
  842.  
  843.     values.function = GXcopy;
  844.     values.foreground = appInfo->currentColor;
  845.     values.line_width = HIGHLIGHT_THICKNESS;
  846.     XChangeGC(XtDisplay(w), appInfo->rectGC, valueMask, &values);
  847.  
  848. }
  849.  
  850.  
  851. /* This procedure returns the values of the current rectangle outline */
  852. static void
  853. #ifdef _NO_PROTO
  854. OutlineGetDimensions(x, y, width, height)
  855. Position *x;
  856. Position *y;
  857. Dimension *width;
  858. Dimension *height;
  859. #else
  860. OutlineGetDimensions(Position *x, Position *y, Dimension *width,
  861. Dimension *height)
  862. #endif /* _NO_PROTO */
  863. {
  864.  
  865.     if (appInfo->rectX < appInfo->rectX2) {
  866.         *x = appInfo->rectX;
  867.         *width = appInfo->rectX2 - *x;
  868.     } else {
  869.         *x = appInfo->rectX2;
  870.         *width = appInfo->rectX - *x;
  871.     }
  872.  
  873.     if (appInfo->rectY < appInfo->rectY2) {
  874.         *y = appInfo->rectY;
  875.         *height = appInfo->rectY2 - *y;
  876.     } else {
  877.         *y = appInfo->rectY2;
  878.         *height = appInfo->rectY - *y;
  879.     }
  880.  
  881. }
  882.  
  883.  
  884. static void
  885. #ifdef _NO_PROTO
  886. OutlineDraw(w)
  887. Widget w;
  888. #else
  889. OutlineDraw(Widget w)
  890. #endif /* _NO_PROTO */
  891. {
  892.  
  893.     Position    x, y;
  894.     Dimension    width, height;
  895.  
  896.     OutlineGetDimensions(&x, &y, &width, &height);
  897.  
  898.     XDrawRectangle(XtDisplay(w), XtWindow(w), appInfo->rectGC,
  899.                    x, y, width, height);
  900.  
  901. }
  902.  
  903.  
  904. /* This procedure sets intializes the drawing positions */
  905. static void
  906. #ifdef _NO_PROTO
  907. OutlineSetPosition(x, y)
  908. Position x;
  909. Position y;
  910. #else
  911. OutlineSetPosition(Position x, Position y)
  912. #endif /* _NO_PROTO */
  913. {
  914.  
  915.     appInfo->rectX = appInfo->rectX2 = x;
  916.     appInfo->rectY = appInfo->rectY2 = y;
  917.  
  918. }
  919.  
  920.  
  921. /* This procedure resets outline end position */
  922. static void
  923. #ifdef _NO_PROTO
  924. OutlineResetPosition(x, y)
  925. Position x;
  926. Position y;
  927. #else
  928. OutlineResetPosition(Position x, Position y)
  929. #endif /* _NO_PROTO */
  930. {
  931.  
  932.     appInfo->rectX2 = x;
  933.     appInfo->rectY2 = y;
  934.  
  935. }
  936.  
  937.  
  938. /* This action procedure begins creating a rectangle at the x,y position
  939.  * of the button event if a rectangle doesn't already exist at
  940.  * that position.  Otherwise is raises the rectangle to the top
  941.  * of the drawing area.
  942.  */
  943. /* ARGSUSED */
  944. void
  945. #ifdef _NO_PROTO
  946. StartRect(w, event, params, num_params)
  947. Widget w;
  948. XEvent *event;
  949. String *params;
  950. Cardinal *num_params;
  951. #else
  952. StartRect(Widget w, XEvent *event, String *params, Cardinal *num_params)
  953. #endif /* _NO_PROTO */
  954. {
  955.  
  956.     Display *display = XtDisplay(w);
  957.     RectPtr rect;
  958.     Position x = event->xbutton.x;
  959.     Position y = event->xbutton.y;
  960.  
  961.     rect = RectFind(x, y);
  962.  
  963.     /* if there isn't a rectangle at this position, begin creating one */
  964.     if (!rect) {
  965.  
  966.         appInfo->creatingRect = True;
  967.         /* set gc for drawing rubberband outline for rectangles */
  968.         SetXorGC(w);
  969.         /* set the initial outline positions */
  970.         OutlineSetPosition(x, y);
  971.         /* Draw the rectangle */
  972.         OutlineDraw(w);
  973.  
  974.     }
  975.     else
  976.         RectRaise(w, rect);
  977.  
  978. }
  979.  
  980.  
  981. /* This action procedure extends the drawing of the outline
  982.  * for the rectangle to be created.
  983.  */
  984. /* ARGSUSED */
  985. void
  986. #ifdef _NO_PROTO
  987. ExtendRect(w, event, params, num_params)
  988. Widget w;
  989. XEvent *event;
  990. String *params;
  991. Cardinal *num_params;
  992. #else
  993. ExtendRect(Widget w, XEvent *event, String *params, Cardinal *num_params)
  994. #endif /* _NO_PROTO */
  995. {
  996.  
  997.     if (appInfo->creatingRect) {
  998.  
  999.         /* erase the old outline */
  1000.         OutlineDraw(w);
  1001.         /* set the new outline end positions */
  1002.         OutlineResetPosition(event->xbutton.x, event->xbutton.y);
  1003.         /* redraw the outline */
  1004.         OutlineDraw(w);
  1005.  
  1006.     }
  1007.  
  1008. }
  1009.  
  1010.  
  1011. /* This action procedure creates a rectangle depending on the
  1012.  * dimensions set in the StartRect and ExtendRect action procs.
  1013.  */
  1014. /* ARGSUSED */
  1015. void
  1016. #ifdef _NO_PROTO
  1017. EndRect(w, event, params, num_params)
  1018. Widget w;
  1019. XEvent *event;
  1020. String *params;
  1021. Cardinal *num_params;
  1022. #else
  1023. EndRect(Widget w, XEvent *event, String *params, Cardinal *num_params)
  1024. #endif /* _NO_PROTO */
  1025. {
  1026.  
  1027.     Position     x, y;
  1028.     Dimension    width, height;
  1029.     RectPtr     rect;
  1030.  
  1031.  
  1032.     if (appInfo->creatingRect) {
  1033.  
  1034.         /* erase the last outline */
  1035.         OutlineDraw(w);
  1036.         /* return GC to original state */
  1037.         SetNormGC(w);
  1038.  
  1039.         /* Get the outline dimensions for creating the rectangle */
  1040.         OutlineGetDimensions(&x, &y, &width, &height);
  1041.  
  1042.         /* we don't want to create zero width or height rectangles */
  1043.         if (width == 0 || height == 0){
  1044.             appInfo->creatingRect = False;
  1045.             return;
  1046.         }
  1047.  
  1048.         rect = RectCreate(x, y, width, height,
  1049.                           GetColor(RECT_START_COLOR), XmUNSPECIFIED_PIXMAP);
  1050.  
  1051.         RectDraw(XtDisplay(w), XtWindow(w), rect);
  1052.         RectRegister(rect, x, y);
  1053.         appInfo->creatingRect = False;
  1054.  
  1055.     }
  1056.  
  1057. }
  1058.  
  1059.  
  1060. /* The procedure assigns new translations the the given widget */
  1061. static void
  1062. #ifdef _NO_PROTO
  1063. SetupTranslations(widget, new_translations)
  1064. Widget widget;
  1065. char *new_translations;
  1066. #else
  1067. SetupTranslations(Widget widget, char *new_translations)
  1068. #endif /* _NO_PROTO */
  1069. {
  1070.  
  1071.     XtTranslations new_table;
  1072.  
  1073.     new_table = XtParseTranslationTable(new_translations);
  1074.     XtOverrideTranslations(widget, new_table);
  1075.  
  1076. }
  1077.  
  1078.  
  1079. /* This procedure handles exposure events and makes a call to 
  1080.  * RedrawRectangles() to redraw the rectangles
  1081.  * The rectangles at the top of the table are drawn first.
  1082.  */
  1083. /* ARGSUSED */
  1084. static void
  1085. #ifdef _NO_PROTO
  1086. HandleExpose(w, closure, call_data)
  1087. Widget w;
  1088. XtPointer closure;
  1089. XtPointer call_data;
  1090. #else
  1091. HandleExpose(Widget w, XtPointer closure, XtPointer call_data)
  1092. #endif /* _NO_PROTO */
  1093. {
  1094.     RedrawRectangles(w);
  1095. }
  1096.  
  1097.  
  1098. /* This procedure sets up the drawing area */
  1099. static void
  1100. #ifdef _NO_PROTO
  1101. CreateDrawingArea(parent)
  1102. Widget parent;
  1103. #else
  1104. CreateDrawingArea(Widget parent)
  1105. #endif /* _NO_PROTO */
  1106. {
  1107.  
  1108.     static char da_translations[] = 
  1109.         "#replace <Btn2Down>: StartMove() \n\
  1110.         <Btn1Down>: StartRect() \n\
  1111.         <Btn1Motion>: ExtendRect() \n\
  1112.         <Btn1Up>: EndRect() \n\
  1113.         c <Key>t: XtDisplayTranslations()";
  1114.  
  1115.     Arg             args[10];
  1116.     int             n = 0;
  1117.     XtTranslations    new_table;
  1118.  
  1119.     new_table = XtParseTranslationTable(da_translations);
  1120.  
  1121.     /* create drawing area at the top of the form */
  1122.     n = 0;
  1123.     XtSetArg(args[n], XmNtranslations, new_table); n++;
  1124.     XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); n++;
  1125.     XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++;
  1126.     XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); n++;
  1127.     XtSetArg(args[n], XmNwidth, 295); n++;
  1128.     XtSetArg(args[n], XmNheight, 180); n++;
  1129.     XtSetArg(args[n], XmNresizePolicy, XmRESIZE_NONE); n++;
  1130.     XtSetArg(args[n], XmNbackground, GetColor(DRAW_AREA_BG_COLOR)); n++;
  1131.     XtSetArg(args[n], XmNforeground, GetColor(DRAW_AREA_FG_COLOR)); n++;
  1132.     drawingArea = XmCreateDrawingArea(parent, "drawingArea", args, n);
  1133.     XtManageChild(drawingArea);
  1134.  
  1135.     /* add expose callback to redisplay rectangles */
  1136.     XtAddCallback(drawingArea, XmNexposeCallback, HandleExpose, 
  1137.                   (XtPointer) NULL);
  1138.  
  1139. }
  1140.  
  1141.  
  1142. /* This procedure sets up the area for obtaining rectangle colors */
  1143. static void
  1144. #ifdef _NO_PROTO
  1145. CreateColorPushButtons(parent, separator)
  1146. Widget parent;
  1147. Widget separator;
  1148. #else
  1149. CreateColorPushButtons(Widget parent, Widget separator)
  1150. #endif /* _NO_PROTO */
  1151. {
  1152.  
  1153.     static char label_translations[] = "<Btn2Down>: ColorRect()";
  1154.     Widget         bulletinBoard;
  1155.     Widget         children[6];
  1156.     XmString    csString;
  1157.     Arg         args[10];
  1158.     int         n = 0;
  1159.  
  1160.     /* Creating an empty compound string so the labels will have no text. */
  1161.     csString = XmStringCreateSimple("");
  1162.  
  1163.     /* Creating 6 color labels */
  1164.     n = 0;
  1165.     XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++;
  1166.     XtSetArg(args[n], XmNtopWidget, separator); n++;
  1167.     XtSetArg(args[n], XmNtopOffset, 2); n++;
  1168.     XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++;
  1169.     XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); n++;
  1170.     XtSetArg(args[n], XmNwidth, 295); n++;
  1171.     bulletinBoard = XmCreateBulletinBoard(parent, "buletinBoard", args, n);
  1172.     XtManageChild(bulletinBoard);
  1173.  
  1174.     n = 0;
  1175.     XtSetArg(args[n], XmNx, BOX_X_MARGIN); n++;
  1176.     XtSetArg(args[n], XmNy, BOX_Y_MARGIN); n++;
  1177.     XtSetArg(args[n], XmNwidth, BOX_WIDTH); n++;
  1178.     XtSetArg(args[n], XmNheight, BOX_HEIGHT); n++;
  1179.     XtSetArg(args[n], XmNlabelString, csString); n++;
  1180.     XtSetArg(args[n], XmNbackground, GetColor(LABEL1_COLOR)); n++;
  1181.     XtSetArg(args[n], XmNborderWidth, 1); n++;
  1182.     children[0] = XmCreatePushButton(bulletinBoard, "PushButton1", args, n);
  1183.  
  1184.     /* add translations for manipulating rectangles */
  1185.     SetupTranslations(children[0], label_translations);
  1186.  
  1187.     n = 0;
  1188.     XtSetArg(args[n], XmNx, BOX_X_MARGIN + BOX_X_OFFSET); n++;
  1189.     XtSetArg(args[n], XmNy, BOX_Y_MARGIN); n++;
  1190.     XtSetArg(args[n], XmNwidth, BOX_WIDTH); n++;
  1191.     XtSetArg(args[n], XmNheight, BOX_HEIGHT); n++;
  1192.     XtSetArg(args[n], XmNlabelString, csString); n++;
  1193.     XtSetArg(args[n], XmNbackground, GetColor(LABEL2_COLOR)); n++;
  1194.     XtSetArg(args[n], XmNborderWidth, 1); n++;
  1195.     children[1] = XmCreatePushButton(bulletinBoard, "PushButton1", args, n);
  1196.  
  1197.     /* add translations for manipulating rectangles */
  1198.     SetupTranslations(children[1], label_translations);
  1199.  
  1200.     n = 0;
  1201.     XtSetArg(args[n], XmNx, BOX_X_MARGIN + (2 * BOX_X_OFFSET)); n++;
  1202.     XtSetArg(args[n], XmNy, BOX_Y_MARGIN); n++;
  1203.     XtSetArg(args[n], XmNwidth, BOX_WIDTH); n++;
  1204.     XtSetArg(args[n], XmNheight, BOX_HEIGHT); n++;
  1205.     XtSetArg(args[n], XmNlabelString, csString); n++;
  1206.     XtSetArg(args[n], XmNbackground, GetColor(LABEL3_COLOR)); n++;
  1207.     XtSetArg(args[n], XmNborderWidth, 1); n++;
  1208.     children[2] = XmCreatePushButton(bulletinBoard, "PushButton3", args, n);
  1209.  
  1210.     /* add translations for manipulating rectangles */
  1211.     SetupTranslations(children[2], label_translations);
  1212.  
  1213.     n = 0;
  1214.     XtSetArg(args[n], XmNx, BOX_X_MARGIN); n++;
  1215.     XtSetArg(args[n], XmNy, BOX_Y_MARGIN + BOX_Y_OFFSET); n++;
  1216.     XtSetArg(args[n], XmNwidth, BOX_WIDTH); n++;
  1217.     XtSetArg(args[n], XmNheight, BOX_HEIGHT); n++;
  1218.     XtSetArg(args[n], XmNlabelString, csString); n++;
  1219.     XtSetArg(args[n], XmNbackground, GetColor(LABEL4_COLOR)); n++;
  1220.     XtSetArg(args[n], XmNborderWidth, 1); n++;
  1221.     children[3] = XmCreatePushButton(bulletinBoard, "PushButton4", args, n);
  1222.  
  1223.     /* add translations for manipulating rectangles */
  1224.     SetupTranslations(children[3], label_translations);
  1225.  
  1226.     n = 0;
  1227.     XtSetArg(args[n], XmNx, BOX_X_MARGIN + BOX_X_OFFSET); n++;
  1228.     XtSetArg(args[n], XmNy, BOX_Y_MARGIN + BOX_Y_OFFSET); n++;
  1229.     XtSetArg(args[n], XmNwidth, BOX_WIDTH); n++;
  1230.     XtSetArg(args[n], XmNheight, BOX_HEIGHT); n++;
  1231.     XtSetArg(args[n], XmNtopWidget, children[0]); n++;
  1232.     XtSetArg(args[n], XmNlabelString, csString); n++;
  1233.     XtSetArg(args[n], XmNbackground, GetColor(LABEL5_COLOR)); n++;
  1234.     XtSetArg(args[n], XmNborderWidth, 1); n++;
  1235.     children[4] = XmCreatePushButton(bulletinBoard, "PushButton5", args, n);
  1236.  
  1237.     /* add translations for manipulating rectangles */
  1238.     SetupTranslations(children[4], label_translations);
  1239.  
  1240.     n = 0;
  1241.     XtSetArg(args[n], XmNx, BOX_X_MARGIN + (2 * BOX_X_OFFSET)); n++;
  1242.     XtSetArg(args[n], XmNy, BOX_Y_MARGIN + BOX_Y_OFFSET); n++;
  1243.     XtSetArg(args[n], XmNwidth, BOX_WIDTH); n++;
  1244.     XtSetArg(args[n], XmNheight, BOX_HEIGHT); n++;
  1245.     XtSetArg(args[n], XmNlabelString, csString); n++;
  1246.     XtSetArg(args[n], XmNbackground, GetColor(LABEL6_COLOR)); n++;
  1247.     XtSetArg(args[n], XmNborderWidth, 1); n++;
  1248.     children[5] = XmCreatePushButton(bulletinBoard, "PushButton6", args, n);
  1249.  
  1250.     /* add translations for manipulating rectangles */
  1251.     SetupTranslations(children[5], label_translations);
  1252.  
  1253.     /* Managing the children all at once helps performance */
  1254.     XtManageChildren(children, 6);
  1255.  
  1256.     /* Freeing compound string.  It is no longer necessary. */
  1257.     XmStringFree(csString);
  1258.  
  1259. }
  1260.  
  1261.  
  1262. /* This procedure initalizes the rectangle display table */
  1263. void
  1264. #ifdef _NO_PROTO
  1265. InitializeRectDpyTable()
  1266. #else
  1267. InitializeRectDpyTable(void)
  1268. #endif /* _NO_PROTO */
  1269. {
  1270.     /*
  1271.      * Initialize display table.  This is used to maintain the
  1272.      * order in which the rectangles are displayed
  1273.      */
  1274.     appInfo->rectDpyTable = (RectPtr *) XtMalloc((unsigned)sizeof(RectPtr));
  1275.  
  1276.     /* Initialize rectangle counter.  This is used in reallocing the tables */
  1277.     appInfo->rectsAllocd = 1;
  1278.  
  1279. }
  1280.  
  1281.  
  1282. /* This procedure creates the components to be displayed */
  1283. void
  1284. #ifdef _NO_PROTO
  1285. CreateLayout()
  1286. #else
  1287. CreateLayout(void)
  1288. #endif /* _NO_PROTO */
  1289. {
  1290.  
  1291.     Widget    mainWindow, form, separator;
  1292.     Arg     args[10];
  1293.     int     n = 0;
  1294.  
  1295.     /* Create main window */
  1296.     mainWindow = XmCreateMainWindow(topLevel, "mainWindow", args, n);
  1297.     XtManageChild(mainWindow);
  1298.  
  1299.     /* Create form for hold drawing area, separator, and color labels */
  1300.     n = 0;
  1301.     XtSetArg(args[n], XmNwidth, 300); n++;
  1302.     form = XmCreateForm(mainWindow, "form", args, n);
  1303.     XtManageChild(form);
  1304.  
  1305.     /* Create area for drawing rectangles */
  1306.     CreateDrawingArea(form);
  1307.  
  1308.     /* Create separator to separate drawing area from color labels */
  1309.     n = 0;
  1310.     XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++;
  1311.     XtSetArg(args[n], XmNtopWidget, drawingArea); n++;
  1312.     XtSetArg(args[n], XmNtopOffset, 5); n++;
  1313.     XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++;
  1314.     XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); n++;
  1315.     XtSetArg(args[n], XmNwidth, 300); n++;
  1316.     separator = XmCreateSeparatorGadget(form, "separator", args, n);
  1317.     XtManageChild(separator);
  1318.  
  1319.     /* Create color labels for changing colors of buttons */
  1320.     CreateColorPushButtons(form, separator);
  1321.  
  1322.     /* Make form the work window of the main window */
  1323.     n = 0;
  1324.     XtSetArg(args[n], XmNworkWindow, form); n++;
  1325.     XtSetValues(mainWindow, args, n);
  1326.  
  1327. }
  1328.  
  1329.  
  1330. /* This procedure initializes the GC for drawing rectangles */
  1331. void
  1332. #ifdef _NO_PROTO
  1333. CreateRectGC()
  1334. #else
  1335. CreateRectGC(void)
  1336. #endif /* _NO_PROTO */
  1337. {
  1338.  
  1339.     XGCValues    values;
  1340.  
  1341.     values.line_style = LineSolid;
  1342.     values.line_width = HIGHLIGHT_THICKNESS;
  1343.     values.foreground = appInfo->currentColor = GetColor(RECT_START_COLOR);
  1344.     appInfo->rectGC = XCreateGC(XtDisplay(topLevel), XtWindow(drawingArea),
  1345.                       GCLineStyle | GCLineWidth | GCForeground, &values);
  1346.  
  1347. }
  1348.